﻿using System.Linq;
using System.Web.Mvc;

namespace PaceR.Web.MvcModels
{
    public sealed class MvcCommand
    {
        private static readonly string _commandPrefix = "__0_Command:";
        private static readonly string _argPrefix = "Argument:";
        private static readonly string _commandNameFormat = "__0_Command:{0};Argument:{1}";
        private static readonly IModelBinder _binder = new MvcCommandBinder();

        public MvcCommand()
            : this(null)
        { }

        public MvcCommand(string encodedCommand)
        {
            if (ValidEncoding(encodedCommand))
            {
                var fields = encodedCommand.Split(new char[] { ';' }, 2);
                if (fields.Count() == 2)
                {
                    int length = _commandPrefix.Length;
                    if (fields[0].Length > length) CommandName = fields[0].Substring(length);
                    length = _argPrefix.Length;
                    if (fields[1].Length > length) CommandArgument = fields[1].Substring(length);
                }
            }
        }

        public string CommandName { get; set; }
        public string CommandArgument { get; set; }

        public override string ToString()
        {
            return string.Format(_commandNameFormat, CommandName, CommandArgument);
        }

        public static IModelBinder Binder()
        {
            return _binder;
        }

        private bool ValidEncoding(string encodedCommand)
        {
            return !string.IsNullOrEmpty(encodedCommand)
                && encodedCommand.Contains(_commandPrefix)
                && encodedCommand.Contains(_argPrefix);
        }

        private sealed class MvcCommandBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                var formCollection = new FormCollection(controllerContext.HttpContext.Request.Form);
                var key = formCollection.AllKeys.FirstOrDefault(k => k.StartsWith(_commandPrefix));
                if (!string.IsNullOrEmpty(key))
                {
                    return new MvcCommand(key);
                }
                return null;
            }
        }
    }
}
